#include <cstdio>
#include <algorithm>
#include <cstring>
#define _clr(x,a) memset(x,a,sizeof(x));
using namespace std;
const int INF=0x3f3f3f3f;
const int N=200020;
int p[N];
//sum数组就表示该点到其前驱节点（非根节点）的距离，有正负 区间从左到右值为负 区间从右到左值为正
int sum[N];
int find(int x){
    if(p[x]==x){
        return x;
    }
    int t=p[x];
    p[x]=find(p[x]);
    //压缩路径，所以这个节点到前驱元的距离要加上这个节点的前驱元到前前驱元的距离
    sum[x]+=sum[t];
    return p[x];
}
bool join(int a,int b,int Sum){
    int fa=find(a);
    int fb=find(b);
    printf("--a:%d--b:%d--\n",a,b);
    printf("--fa:%d--fb:%d--\n",fa,fb);
    if(fa==fb){
        //有相同的前驱元（根），减号是因为区间有正负，不等即矛盾
        if(sum[b]-sum[a]==Sum){
            return false;
        }
        else{
            return true;
        }
    }
    //合并
    else{
        //将b连在a上
        p[fb]=fa;
        //线段图表示    b-------fb
        //                 a------------fa
        //b到fb就是sum[b]  a到fa就是sum[a] 而当前根节点为fa,所以所求的sum[fb]就是sum[a]+Sum(a,b)-sum[b]
        //因为sum有正负号，所以方向没问题
        sum[fb]=sum[a]+Sum-sum[b];
        printf("%d %d\n",sum[fa],sum[fb]);
        return false;
    }

}
int main(void){
    freopen("data.txt","r",stdin);
    int n,m;
	while(~scanf("%d%d",&n,&m)){
		int cnt=0;
        int x;
        int y;
        int Sum;
		for(int i=0;i<=n;i++){
            p[i]=i;
            sum[i]=0;
        }
		while(m--){
			scanf("%d%d%d",&x,&y,&Sum);
			if(join(x-1,y,Sum)){
                cnt++;
                printf("x:%d  y:%d\n",x,y);
            }
    	}
        printf("sum:\n");
        for(int i=0;i<=n;i++){
            printf("%d ",sum[i]);
        }
        printf("\n");
        for(int i=0;i<=n;i++){
            printf("%d ",p[i]);
        }
        printf("\n");
		printf("%d\n",cnt);
	}
    return 0;
}
